#pragma once

#include <iostream>
#include <fstream>
#include <string>
#include <unordered_map>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;

const string ADMIN_USERNAME = "admin";
const string ADMIN_PASSWORD = "admin123";
const string DATA_C_FILE = "customers.txt";
const string DATA_P_FILE = "products.txt";

// 管理员类
class Admin
{
private:
    string username;
    string password;

public:
    // 提供默认构造函数
    Admin(const string &u = ADMIN_USERNAME, const string &p = ADMIN_PASSWORD)
        : username(u), password(p) {}
    bool login(const string &u, const string &p) const
    {
        return username == u && password == p;
    }
};

// 商品类
class Product
{
private:
    string category;
    string name;
    double price;
    string description;
    int stock;

public:
    Product(const string &c = "", const string &n = "", double p = 0.0, const string &d = "", int s = 0)
        : category(c), name(n), price(p), description(d), stock(s) {}
    void increaseStock(int amount); // 库存同步
    // get-set方法
    string getName() const
    {
        return name;
    }
    double getPrice() const
    {
        return price;
    }
    int getStock() const
    {
        return stock;
    }
    string getCategory() const
    {
        return category;
    }
    string getDescription() const
    {
        return description;
    }
    void setName(const string &n)
    {
        name = n;
    }
    void setPrice(double p)
    {
        price = p;
    }
    void setStock(int s)
    {
        stock = s;
    }
    void setCategory(const string &c)
    {
        category = c;
    }
    void setDescription(const string &d)
    {
        description = d;
    }
    void decreaseStock(int quantity)
    {
        // 验证输入的数量是否为非负数
        if (quantity < 0)
        {
            cerr << "错误：输入的数量不能为负数。" << endl;
            throw invalid_argument("输入的数量必须是非负数");
        }
        // 检查库存是否充足
        if (stock < quantity)
        {
            cerr << "错误：库存不足，当前库存: " << stock << ", 请求数量: " << quantity << endl;
            throw runtime_error("库存不足，无法减少指定数量");
        }

        if (stock >= quantity)
        {
            stock -= quantity;
            cout << "成功减少，当前库存为->" << stock << endl;
        }
    }
};

// 购物车类
class ShoppingCart
{
private:
    unordered_map<string, int> items;                         // 商品名称 -> 购买数量
    unordered_map<string, const Product *> productReferences; // 商品名称 -> 商品指针

public:
    void addProduct(const Product &product, int quantity);           // 添加商品
    void removeProduct(const string &productName);                   // 删除商品
    void modifyQuantity(const string &productName, int newQuantity); // 修改数量
    void displayCart() const;                                        // 显示商品
    int getTotalQuantity() const;                                    // 获取总个数
    double getTotalPrice() const;                                    // 获取总价格
    void clearCart();                                                // 清空购物车

    // 判断购物车是否为空
    bool isEmpty() const;
    // 获取购物车中的商品及数量
    const unordered_map<string, int> &getItems() const;
};

// 顾客类
class Customer
{
private:
    string username;
    string password;
    string name;
    ShoppingCart cart;

public:
    Customer(const string &u = "", const string &p = "",
             const string &n = "userx")
        : username(u), password(p), name(n) {}
    bool changePassword(const string &oldPwd, const string &newPwd)
    {
        if (password == oldPwd)
        {
            password = newPwd;
            return true;
        }
        return false;
    }
    string getUsername() const
    {
        return username;
    }
    string getPassword() const
    {
        return password;
    }
    string getName() const
    {
        return name;
    }
    ShoppingCart &getCart()
    {
        return cart;
    }
};

// 订单类
class Order
{
private:
    string orderId;                   // 订单编号
    time_t createTime;                // 订单创建时间
    string status;                    // 订单状态：待发货、已发货、已签收
    unordered_map<string, int> items; // 商品名称 -> 购买数量
    double totalPrice;                // 订单总价
    string address;                   // 收货地址
    string customerUsername;          // 顾客用户名

public:
    Order(const string &id, const string &username,
          const unordered_map<string, int> &cartItems,
          const unordered_map<string, Product> &products,
          const string &addr);

    // Getters
    string getOrderId() const { return orderId; }
    time_t getCreateTime() const { return createTime; }
    string getStatus() const { return status; }
    unordered_map<string, int> getItems() const { return items; }
    double getTotalPrice() const { return totalPrice; }
    string getAddress() const { return address; }
    string getCustomerUsername() const { return customerUsername; }

    // 修改订单（仅限待发货状态）
    bool updateAddress(const string &newAddress);
    bool cancelOrder(unordered_map<string, Product> &products);

    // 订单状态转换
    bool setStatus(const string &newStatus);
    void displayOrderDetails() const;
};

// 订单列表类
class OrderList
{
private:
    vector<Order> orders;   // 订单集合
    static int nextOrderId; // 下一个订单编号

public:
    // 创建新订单
    string createOrder(Customer &customer,
                      const unordered_map<string, int> &cartItems,
                      unordered_map<string, Product> &products,
                      const string &address);

    // 查询订单
    vector<Order> getCustomerOrders(const string &username) const;
    Order *findOrderById(const string &orderId);

    // 订单状态管理（自动/手动）
    void updateOrderStatuses(); // 自动更新状态
    bool manuallyUpdateStatus(const string &orderId, const string &newStatus);

    // 显示订单
    void displayCustomerOrders(const string &username) const;

    vector<Order> &getOrders();

    bool removeOrder(const string &orderId); // 添加删除订单的方法
};

// 系统管理类
class System
{
private:
    Admin admin;
    // 使用unordered_map管理顾客和商品
    unordered_map<string, Customer> customers;
    unordered_map<string, Product> products;
    OrderList orderList; // 订单列表

    void loadCustomers(); // 从文件中读取顾客信息
    void saveCustomers(); // 将存储在 customers 哈希表中的顾客信息保存到customers.txt 的文本文件中
    void loadProducts();
    void saveProducts();

public:
    System()
        : admin(ADMIN_USERNAME, ADMIN_PASSWORD)
    {
        loadCustomers();
        loadProducts();
    }
    void run();

private:
    void adminLogin();
    void adminMenu();

    void customerMenu(Customer &customer);
    void customerLogin();
    void customerRegister();

    void manageProducts();
    void displayProducts() const;
    void addProduct();
    void modifyProduct();
    void deleteProduct();

    void searchProducts();
    void fuzzySearchProducts(const string &keyword);
    void purchaseProduct(Customer &customer);

    // 第三次添加
    void addToCart(Customer &customer);
    void removeFromCart(Customer &customer);
    void modifyCart(Customer &customer);
    void viewCart(Customer &customer);

    // 第四次添加:新增购物流程相关方法
    void purchaseFromProductList(Customer &customer);
    void purchaseFromCart(Customer &customer);
    void viewOrders(Customer &customer);
    void manageOrders(); // 管理员订单管理
    void modifyOrder(Customer &customer);
    void deleteOrder(Customer &customer);

    void mainMenu();
};
